<html>
<head>
    <style>
        * {
            font-family: 'Consolas', 'Ubuntu Mono', 'Monaco', 'Courier New', Courier, sans-serif;
        }
        body {
            margin: 0;
            padding: 0;
        }
        #files-container {
            padding: 0 10px;
            width: 33%;
            display: flex;
            flex-direction: column;
            max-height: 100vh;
        }
        textarea {
            height: 300px;
        }
        img {
            width: 64px;
        }
        #debug-container {
            width: 66%;
            overflow-x: hidden;
            background: #eaeaea;
            font-size: 0.7rem;
            padding: 10px;
            margin: 0;
        }
        #debug-state,
        #debug-txs,
        #debug-network {
            min-height: 100vh;
        }
        .hidden {
            display: none;
        }
    </style>
</head>
<body>
    <div style='display: flex'>
        <div id='files-container'>
            <h1>git integration</h1>

            <div id="files"></div>
            <br/><br/>
            <strong>script.js output</strong><br/>
            <div id="script-output"></div>
            <br/>
            <strong>redwood.jpg</strong><br/>
            <img src="/demo/redwood.jpg?state_uri=somegitprovider.org/gitdemo" />
            <br/>
            <strong>README.md</strong><br/>
            <textarea id="readme" readonly></textarea>
        </div>
        <div id='debug-container'>
            <button id='btn-view-debug-state' disabled>State</button>
            <button id='btn-view-debug-txs'>Transactions</button>
            <button id='btn-view-debug-network'>Network</button>
            <div id='tab-state'>
                <code>
                    <pre id='debug-state'>
                    </pre>
                </code>
            </div>
            <div id='tab-txs' class='hidden'>
                <code>
                    <pre id='debug-txs'>
                    </pre>
                </code>
            </div>
            <div id='tab-network' class='hidden'>
                <code>
                    <pre id='debug-network'>
                    </pre>
                </code>
            </div>
        </div>
    </div>
    <div id="scriptjs-wrapper">
        <script id="scriptjs" src="/demo/script.js?state_uri=somegitprovider.org/gitdemo"></script>
    </div>
</body>

<script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script>
<script src="/redwood.js"></script>
<script>
    //
    // Redwood setup
    //
    var identity = Redwood.identity.random()

    var currentState = {}
    var mostRecentTxID = null
    var txs = []
    var queue = Redwood.utils.createTxQueue(
        (from, vid, parents, patches) => Redwood.dumb.resolve_state(currentState, from, vid, parents, patches),
        async ({ tx, state }) => {
            mostRecentTxID = tx.id

            // Update the debug state UI
            currentState = state
            txs.push(tx)
            refreshDebugUI()

            // Update the files UI
            try {
                refreshFilesUI()
            } catch (err) {
                // This is almost assuredly because currentState.git.files doesn't exist yet
                console.error('tx recvd ~>', err)
            }
        }
    )

    var braidClient = Redwood.createPeer({
        identity: identity,
        httpHost: '',
        webrtc: true,
        onFoundPeersCallback: (peers) => {
            knownPeers = peers
            refreshDebugUI()
        }
    })

    braidClient.authorize().then(() => {
        braidClient.subscribe({
            stateURI: 'somegitprovider.org/gitdemo',
            keypath: '/',
            txs: true,
            fromTxID: Redwood.utils.genesisTxID,
            callback: queue.defaultTxHandler,
        })
    })

    //
    // script.js-related stuff
    //
    window.i = 0
    setInterval(() => {
        window.i = window.updateScriptValue(window.i)
        document.querySelector('#script-output').innerHTML = '' + window.i
    }, 1000)

    //
    // Files UI
    //
    var filesElem = document.querySelector('#files')
    var scriptWrapperElem = document.querySelector('#scriptjs-wrapper')
    var readmeElem = document.querySelector('#readme')
    var imageElem = document.querySelector('img')
    async function refreshFilesUI() {
        // Reload README.md and redwood.jpg
        readmeElem.innerHTML = await (await fetch('/demo/README.md?state_uri=somegitprovider.org/gitdemo&' + new Date().getTime())).text()
        imageElem.src = '/demo/redwood.jpg?state_uri=somegitprovider.org/gitdemo&' + new Date().getTime() // force a refresh of the image

        // Reload script.js
        scriptWrapperElem.removeChild(document.querySelector('#scriptjs'))
        var newScript = document.createElement('script')
        newScript.id = 'scriptjs'
        newScript.type = 'text/javascript'
        newScript.src = '/demo/script.js?state_uri=somegitprovider.org/gitdemo&' + new Date().getTime()
        scriptWrapperElem.appendChild(newScript)

        // Reload the files view
        let newHTML = '<strong>Git repo:</strong><br/>'
        try {
            var commit = currentState.refs.heads.master.HEAD
            var files = currentState.commits[commit].files
            renderDir(files || {}, [], 1)
        } catch (err) {}

        filesElem.innerHTML = newHTML

        function renderDir(dir, keypath, currentIndent) {
            for (let filename of Object.keys(dir)) {
                let pathParts = [].concat(keypath, [filename])
                newHTML +=  `<div style="margin-left: ${currentIndent * 20}px">- <a href="/demo/${pathParts.join('/')}?state_uri=somegitprovider.org/gitdemo">${filename}</a></div>`
                if (!isFile(dir[filename])) {
                    renderDir(dir[filename], [].concat(keypath, [filename]), currentIndent + 1)
                }
            }
        }

        function isFile(entry) {
            return !!entry['Content-Type']
        }
    }

    //
    // Debug UI
    //
    var knownPeers = {}
    var currentDebugTab = 'state'
    var debugTabButtonState = document.getElementById('btn-view-debug-state')
    var debugTabButtonTxs = document.getElementById('btn-view-debug-txs')
    var debugTabButtonNetwork = document.getElementById('btn-view-debug-network')
    var debugStateElem = document.getElementById('debug-state')
    var debugTxsElem = document.getElementById('debug-txs')
    var debugNetworkElem = document.getElementById('debug-network')
    var debugStateTab = document.getElementById('tab-state')
    var debugTxsTab = document.getElementById('tab-txs')
    var debugNetworkTab = document.getElementById('tab-network')
    function refreshDebugUI() {
        debugStateElem.innerHTML = JSON.stringify(currentState, null, 4)
        debugTxsElem.innerHTML = JSON.stringify(txs, null, 4)
        debugNetworkElem.innerHTML = JSON.stringify(knownPeers, null, 4)
    }

    function changeDebugUITab() {
        if (currentDebugTab === 'state') {
            debugStateTab.classList.remove('hidden')
            debugTxsTab.classList.add('hidden')
            debugNetworkTab.classList.add('hidden')
            debugTabButtonState.disabled = true
            debugTabButtonTxs.disabled = false
            debugTabButtonNetwork.disabled = false
        } else if (currentDebugTab === 'txs') {
            debugStateTab.classList.add('hidden')
            debugTxsTab.classList.remove('hidden')
            debugNetworkTab.classList.add('hidden')
            debugTabButtonState.disabled = false
            debugTabButtonTxs.disabled = true
            debugTabButtonNetwork.disabled = false
        } else if (currentDebugTab === 'network') {
            debugStateTab.classList.add('hidden')
            debugTxsTab.classList.add('hidden')
            debugNetworkTab.classList.remove('hidden')
            debugTabButtonState.disabled = false
            debugTabButtonTxs.disabled = false
            debugTabButtonNetwork.disabled = true
        }
    }
    debugTabButtonState.addEventListener('click', () => {
        currentDebugTab = 'state'
        changeDebugUITab()
    })
    debugTabButtonTxs.addEventListener('click', () => {
        currentDebugTab = 'txs'
        refreshDebugUI()
        changeDebugUITab()
    })
    debugTabButtonNetwork.addEventListener('click', () => {
        currentDebugTab = 'network'
        changeDebugUITab()
    })

</script>
</html>
